/*
PARI/GP scripts related to tetrations
=============================================================
File: TetrationLimit.txt    
Link: https://oeis.org/wiki/File:TetrationLimit.txt
=============================================================
*/


TetrationLimit(x,monit=0) =
/* ----------------------------------------------------------
 Computes the infinite power tower, i.e., the tetration limit
 T(x) = lim[n->inf] x^x^...^x (^ appearing n times), written
 also as T(x) = lim[n->inf] x^^n.

 The optional argument "monit" (default value 0), if set to
 a non-zero value, makes the script to display (monitor) the
 progress of the iterations.  
 
 For non-negative argument, the following behaviors can occur:
 a) When x > E^(1/E), T(x) is infinite (the script issues an
    error message).
 b) When x = E^(1/E), T(x) = E, but since one never knows what
    the tiniest rounding error might cause in this case, the
    script tests for it explicitely.
 c) When 1 < x < E^(1/E), the limit y = T(x) exists. It also
    equals the smaller of the two y-solutions of y = x^y.
 d) When x = 1, T(x) exists and is 1, and the script works.
 e) When 1/e^e <= x < 1, the limit T(x) exists and the script
    finds it. T(x) is also the unique y-solution of y*x^y = 1.
 f) When 0 < x < 1/E^E, the sequence x^^n oscillates between
    two "branches", one for even n, and one for odd n, both of
    which converge to two, distinct values. The script returns
    the result for even-valued n's. However, a global variable
    called oddval is set to the result for odd-valued n's.
 g) When x = 0, the script returns 0 and sets 1 into oddval.

 Notes: - The script is not optimized. Values of n are simply
    incremented by 16 (starting at 16) until the result is
    fully stable. Efficiency was not an issue here.
        - In case (e), T(x) = LambertW(log(1/x))/log(1/x) and,
    since PARI (versions >= 2.6.1) has now a fast lambertw(x)
    implementation, you can prefer this method.
        - In case (f), the y = LambertW(log(1/x))/log(1/x)
    evaluates to the unique y-solution  of y*x^y = 1 which,
    however, is neither of the two limits of T(x), the even-n
    one Te(x) and the odd-n To(x). The following applies:
    Te(x) < y < To(x) and x^Te(x) = To(x), x^To(x) = Te(x).
        - The behaviour for negative and complex arguments is
    complicated and exhibits multi-valued termination cycles
    in some regions. The script may be used, but it might end
    in non-convergent cyclic loop. It runs fine with values
    such as I, 1+I, -0.05, but it hangs with -0.5).
    More is coming. For now, use it at your own risk.  
 
 User instructions:  
 1) Before calling this function, make sure that your real-
    numbers precision is set as desired (e.g., \p 2020).
 2) Run the script. If it exits with a value, then ...
 3) ... compare the returned value with oddval.
 4) In cases c,d,e the two values must be exactly identical.
 5) In case f, they differ and correspond to the even-n and
    odd-n limits, respectively.
---------------------------------------------------------- */
{
  global(oddval);
  my(m,i,p0,p1,a,e,ee,incr,eps);
  eps = 10^(-default(realprecision)+1);
  if (type(x)=="t_REAL",
    if (abs(x)<eps, oddval=1.0; return(0.0));
    e  = exp(1.0);
    ee = e^(1/e);
    if (x >  ee, error("Argument > e^(1/e)"));
    if (abs(x-ee)<eps, oddval=e;return(e));
  );
  incr = 16;
  m  = incr;
  p0 = x;
  while (1,
    for(i=1,m,p0=x^p0;);
    p1 = x^(x^p0);
    if (monit, print(m));
    if(abs(p1-p0) < eps, break);
    m += incr;
  );
  oddval = x^p0;
  return(p0);
}


/*
=============================================================
  Contributed to OEIS Wiki by Stanislav Sykora
=============================================================
*/

